package top.hkyzf.util.hook;

import com.mojang.logging.LogUtils;
import org.slf4j.Logger;
import top.hkyzf.event.TickEvents;
import top.hkyzf.util.ClientConfig;
import top.hkyzf.util.OneKeyContext;
import top.hkyzf.util.Utils;
import top.hkyzf.util.movement.OneKeyInput;
import top.hkyzf.util.movement.Rotation;

/**
 * description: 挂机类
 * @author zhufeng
 * @date 2022/8/19 17:20
 * @version V1.0
 */
public class OnHook {
    /**
     * 获取一个 slf4j 日志记录器
     */
    private static final Logger LOGGER = LogUtils.getLogger();
    /**
     * Mod 所处的上下文环境
     */
    private final OneKeyContext context = OneKeyContext.getInstance();
    /**
     * 挂机线程使用的锁
     */
    private final Object hookLock = context;

    /**
     * 另起线程开始挂机
     */
    public void onHookInNewThread() {
        // 设置强制停止标志
        context.setForceStop(false);
        if (Thread.holdsLock(hookLock)) {
            LOGGER.error("已有线程在挂机，暂时不可挂机！");
            return;
        }
        // 在世界外，未开始游戏，直接返回
        if (TickEvents.Type.OUT.equals(context.getInTheWorld())) {
            return;
        }
        Utils.getExecutor().execute(() -> {
            synchronized (hookLock) {
                // 设置为控制状态
                context.setInControl(true);
                int index = 1;
                while (!context.isForceStop()) {
                    try {
                        // 选方向
//                        OneKeyInput input = getDirection(index);
                        // 稍微等一下确保控制状态更新
                        hookLock.wait(200);
                        // 设置方向
//                        context.getInputPressDownMap().put(input, true);
//                        LOGGER.info("即将前进的方向：{}", input);
                        // 移动的时间
//                        hookLock.wait(Utils.getRandom(300, 700));
                        // 清除所有的输入状态
//                        context.getInputPressDownMap().clear();
                        // 获取合法的转身度数值 [-180, 180)
                        float yaw = Rotation.normalizeYaw((float) (Math.random()-0.5) * 360);
                        // 获取合法的抬头度数值 [-90, 90)
                        float pitch = Rotation.clampPitch((float) (Math.random()-0.5) * 180);
                        context.getMc().player.setYRot(yaw);
                        context.getMc().player.setXRot(pitch);
                        // 等待 [2-5] 分钟继续下一个动作
                        hookLock.wait(Utils.getRandom(
                                ClientConfig.RANDOM_MIN_HOOK_SECOND.get() * 1000,
                                ClientConfig.RANDOM_MAX_HOOK_SECOND.get() * 1000));
                    } catch (InterruptedException ignored) {
                    }
                    index++;
                    if (index > 4) {
                        index = 1;
                    }
                }
                // 设置为非控制状态
                context.setInControl(false);
            }
        });
    }

    /**
     * 叫醒当前线程，强制停止
     */
    public void forceStopHook() {
        context.setForceStop(true);
        synchronized (hookLock) {
            hookLock.notify();
        }
    }

    /**
     * 通过传入的 code 判断下一个输入的方向
     * @param dir 方向对应的 code 值
     * @return 虚拟输入的移动方向
     */
    private OneKeyInput getDirection(int dir) {
        return switch (dir) {
            case 1 -> OneKeyInput.MOVE_FORWARD;
            case 2 -> OneKeyInput.MOVE_RIGHT;
            case 3 -> OneKeyInput.MOVE_BACK;
            case 4 -> OneKeyInput.MOVE_LEFT;
            default -> OneKeyInput.JUMP;
        };
    }
}
